<?php

namespace app\web;
//*******引用系统开始
use \think\Request;
use \think\View;
use \think\Controller;
//*******引用系统结束
use app\model\Conf as ConfModel;
use app\model\User as UserModel;
use app\model\Group as GroupModel;
use app\model\Node as NodeModel;
use app\model\Auth as AuthModel;
use app\model\Log as LogModel;
//other model
use app\model\Wechat as WechatModel;

class Base extends Controller
{
	protected $view;
	protected $request;
	protected $module;
	protected $controller;
	protected $action;
	protected $domain;

	protected $user;
	protected $wechat;
	protected $access_token;
	protected $jsPackage;
	protected $isLogin = false;

	protected $ConfModel;
	protected $UserModel;
	protected $GroupModel;
	protected $NodeModel;
	protected $AuthModel;
	protected $LogModel;
	//other model
	protected $WechatModel;
	public function __construct()
	{
		$this->ConfModel = new ConfModel();
		$this->UserModel = new UserModel();
		$this->GroupModel = new GroupModel();
		$this->NodeModel = new NodeModel();
		$this->AuthModel = new AuthModel();
		$this->LogModel = new LogModel();
		//other model
		$this->WechatModel = new WechatModel();
		$configs = $this->ConfModel->select();
		$c = [];
		foreach ($configs as $config) {
			$c[$config['conf_key']] = $config['conf_value'];
		}
		config($c);
		$this->init();
	}
	/**
	 * 初始化请求数据
	 *
	 * @return void
	 */
	protected function init()
	{
		$this->view = new view();
		$this->request = Request::instance();
		$this->module = strtolower($this->request->module()) ? strtolower($this->request->module()) : "admin";
		$this->controller = $this->request->controller() ? $this->request->controller() : "Index";
		$this->action = strtolower($this->request->action()) ? strtolower($this->request->action()) : "index";
		$this->domain = $this->request->domain();
		$this->access_token = $this->ConfModel->getAccessToken();
	}
	protected function show()
	{
		return $this->view->fetch();
	}
	public function _empty()
	{
		return $this->show();
	}

	/**
	 * 登录
	 *
	 * @param  string 回调相对地址
	 * @param  bool 是否强制重新登录
	 *
	 * @return void
	 */
	protected function login($callback = "", $needLogin = false)
	{
		$this->user = null;
		$this->wechat = null;
		$wechat_id = cookie('wechat_id');
		$wechat_ticket = cookie('wechat_ticket');

		if (empty($wechat_id) || empty($wechat_ticket)) {
			$needLogin = true;
			$this->isLogin = false;
		}

		if (getTicket($wechat_id) != $wechat_ticket) {
			$needLogin = true;
			$this->isLogin = false;
		}
		$url = "";
		if ($this->request->module() != "index") {
			$url .= strtolower($this->module) . '/';
		} else {
			if ($this->controller != "Index" && $this->action != "index") {
				$url .= strtolower($this->module) . '/';
			}
		}
		if ($this->controller != "Index") {
			$url .= strtolower($this->controller) . '/';
		} else {
			if ($this->action != "index") {
				$url .= strtolower($this->controller) . '/';
			}
		}
		if ($this->action != "index") {
			$url .= strtolower($this->action) . '/';
		}
		if ($needLogin || !empty($callback)) {
			if (!empty($callback)) {
				$url = $callback;
			} else {
				$getArr = Request::instance()->get();
				if (count($getArr) > 0) {
					$url .= "?";
					$i = 0;
					foreach ($getArr as $key => $value) {
						$i++;
						if ($key == "code" || $key == "state" || $key == "from" || $key == "isappinstalled") {
							continue;
						}
						$url .= $key . '=' . $value;
						if ($i < count($getArr)) {
							$url .= "&";
						}
					}
				}
			}

			$callbackWechat = urlencode($this->domain . "/" . strtolower($this->module) . "/callback/");
			header("Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . config("wechat_appid") . "&redirect_uri=" . $callbackWechat . "&response_type=code&scope=snsapi_userinfo&state=" . urlencode($url) . "#wechat_redirect");
			die();
		} else {
			$this->wechat = $this->WechatModel->getWechatById($wechat_id);
		}
		if (!$this->wechat) {
			$this->login(urlencode($url), TRUE);
			die();
		}

		if ($this->request->isAjax()) {
			if ($needLogin) {
				$this->isLogin = false;
			} else {
				$this->isLogin = true;
			}
		}
		if ($this->wechat['wechat_id'] > 10) {
			$this->error("系统维护中，维护时间至02:00，请稍候登录。");
			die();
		}
		$this->wechat['wechat_ticket'] = sha1($this->wechat["wechat_id"] . "x" . $this->wechat['wechat_id']);

		$this->access_token = $this->ConfModel->getAccessToken();
		$this->jsPackage = $this->getSignPackage();
		$this->view->assign('jsPackage', $this->jsPackage);
		$this->view->assign('wechat', $this->wechat);

		//账户状态异常处理
		if ($this->wechat['wechat_status'] != 0) {
			$this->error('您的账户状态异常，请联系管理员处理');
		}

		//     // 是否需要绑定??
		//     //根据自身业务逻辑 可以直接创建用户到user表 或让用户自行注册或绑定
	}

	public function wxcallback($code, $callback)
	{
		$retStr = httpGetFull("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . config("wechat_appid") . "&secret=" . config("wechat_appkey") . "&code={$code}&grant_type=authorization_code");
		$retObj = json_decode($retStr);
		//print_r($retObj);die();
		if (isset($retObj->errcode)) {
			$this->login($callback);
		} else {
			$access_token = $retObj->access_token;
			$openid = $retObj->openid;
			$retStr = httpGetFull("https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN");
			$retObj = json_decode($retStr);
			//print_r($retObj);exit;
			if (isset($retObj->errcode)) {
				$this->login($callback);
			} else {
				$nickname = urlencode($retObj->nickname);
				$sex = urlencode($retObj->sex);
				$headimgurl = urlencode($retObj->headimgurl);
				$wechat = $this->WechatModel->getWechatByOpenid($openid)->find();
				$wechat_id = 0;
				if (empty($wechat)) {
					//注册
					$data = array("wechat_openid" => $openid, "wechat_nick" => $nickname, "wechat_head" => $headimgurl, "wechat_sex" => $sex, "wechat_createtime" => time(), "wechat_updatetime" => time());
					$wechat_id = $this->WechatModel->insertGetId($data);
				} else {
					//更新
					if (!empty($wechat["wechat_remark"])) {
						//如果设置了个性名称 不修改昵称
						$nickname = $wechat['wechat_remark'];
					}
					$this->WechatModel->where('wechat_openid', $openid)->update(array("wechat_nick" => $nickname, "wechat_head" => $headimgurl, "wechat_sex" => $sex, "wechat_updatetime" => time()));
					$wechat_id = $wechat['wechat_id'];
				}
				//301到原来的页面
				cookie('wechat_id', $wechat_id, 3600000);
				cookie('wechat_ticket', getTicket($wechat_id), 3600000);
				header("Location: /" . urldecode($callback));
				die();
			}
		}
	}
	/**
	 * 发送文本客服消息
	 *
	 * @param  string OPENID
	 * @param  string 消息内容
	 *
	 * @return void
	 */
	protected function text($openid, $msg = "Hello Hamm.cn!")
	{
		$data = '{"touser":"' . $openid . '","msgtype":"text","text":{"content":"' . $msg . '"}}';
		$ret = httpPost("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $this->access_token, $data);
		return $ret;
	}

	/**
	 * 发送模板消息
	 *
	 * @param  string OPENID
	 * @param  string 消息头
	 * @param  string 标题
	 * @param  string 内容
	 * @param  string 链接地址
	 *
	 * @return void
	 */
	protected function template($openid, $msg = "msg missing", $title = "title missing", $content = "content missing", $url = "")
	{
		$data = ' {
                    "touser":"' . $openid . '",
                    "template_id":"y2tcBd6YfPq0wehGY8hHDS4IDMuqI4cm7tOGO_bPaLE",
                    "url":"' . $url . '",    
                    "data":{
                        "first": {
                            "value":"' . $msg . '",
                            "color":"#173177"
                        },
                        "keyword1":{
                            "value":"' . $title . '",
                            "color":"#173177"
                        },
                        "keyword2": {
                            "value":"' . date("m-d H:i") . '",
                            "color":"#173177"
                        },
                        "remark":{
                            "value":"\n' . $content . '",
                            "color":"#173177"
                        }
                    }
                }';

		$ret = httpPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $this->access_token, $data);
		return ($ret);
	}

	protected function image($openid, $title = array(), $datas = array())
	{
		$data = ' {
                "touser":"' . $openid . '",
                "msgtype":"news",
                "news":{
                    "articles": [
                     {
                         "title":"' . $title['title'] . '",
                         "description":"",
                         "url":"' . $title['url'] . '",
                         "picurl":"' . $title['img'] . '"
                     }
        ';
		foreach ($datas as $item) {
			$data .= ',{
                 "title":"' . $item['title'] . '",
                 "description":"",
                 "url":"' . $item['url'] . '",
                 "picurl":"' . $item['img'] . '"
             }';
		}
		$data .= '
                     ]
                }
            }';
		//print_r($data);exit;
		$ret = httpPost("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $this->access_token, $data);
		print_r($ret);
		exit;
	}

	/**
	 * 获取签名数据包
	 *
	 * @return void
	 */
	protected function getSignPackage()
	{
		$jsapiTicket = $this->getJsApiTicket();

		// 注意 URL 一定要动态获取，不能 hardcode.
		$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
		//$url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . "?" . $_SERVER['QUERY_STRING'];
		$url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

		$timestamp = time();
		$nonceStr = $this->createNonceStr();

		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

		$signature = sha1($string);

		$signPackage = array("appId" => config("wechat_appid"), "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string);
		return $signPackage;
	}

	/**
	 * 获取JS API的票据
	 *
	 * @return void
	 */
	private function getJsApiTicket()
	{
		$appData = db('conf')->where('conf_key', 'jsticket')->find();
		$jsapiTicket = "";
		if (time() > $appData['conf_int']) {
			//需要重新请求access_token
			$access_token = $this->ConfModel->getAccessToken();
			$retObj = httpGetFull("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi");
			$retObj = json_decode($retObj);

			$jsapiTicket = $retObj->ticket;
			db('conf')->where('conf_key', "jsticket")->update(array("conf_value" => $jsapiTicket, "conf_int" => (time() + 5000)));
		} else {
			//access_token有效
			$jsapiTicket = $appData['conf_value'];
		}
		return $jsapiTicket;
	}

	private function createNonceStr($length = 16)
	{
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$str = "";
		for ($i = 0; $i < $length; $i++) {
			$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
		}
		return $str;
	}
}
